A computing system generally includes a central processing unit that is configured to execute program instructions which are ordered and arranged to execute various tasks. Each central processing unit has a predefined set of instructions capable of execution on that system, referred to as an instruction set. The instruction set executable by a central processing unit defines the instruction set architecture of that central processing unit.
Often, it is desirable to run software written for a particular instruction set architecture on a computing system that has a different, and incompatible, instruction set architecture. To do so, the software must be translated from the instruction set in which it is written to an instruction set compatible with the target central processing unit. This can be done at least two different ways. First, if source code is available, it can be recompiled onto the new instruction set architecture using a compiler specific to that architecture. Second, if source code is not available or if for some other reason the binary program is the desired source from which operation is to be derived, the software can be translated onto the new instruction set architecture by translating the binary program onto the new instruction set architecture on an instruction-by-instruction basis.
To accomplish execution of binary code on a non-native instruction set architecture, the binary code is often translated using an emulator designed for a target instruction set architecture. An emulator is a set of software modules that is configured to execute binary code from its native format in a way that is recognizable on a target computing system executing the target instruction set architecture. This code, referred to as emulation mode code, is parsed by the emulator to detect operators and other information that are then translated to be executed in a manner recognizable on the target computing system.
When emulation mode code is translated and executed on a computing system, the computing system executing that code must typically perform a number of status checking operations concurrently with execution. This is because, when emulation mode code executes in a computing environment, there is no guarantee that specific computing resources have not been altered between execution of operators. For example, arrays can be relocated in memory, resized (larger or smaller), or can be paged into or out from memory. Additionally, working software stacks can be relocated, and code to be executed might be discarded altogether by the emulated operating system. To account for these possibilities, a number of status checks must be performed by the emulator executing in the native operating system, to ensure that any assumptions made regarding locations of objects in memory have not changed between instructions. As a result of this overhead, execution of emulation mode code on a target computing system can be much slower than execution on a native computing system, even if that target computing system has substantially greater computing resources when compared to the native computing system.
For these and other reasons, improvements are desirable.